/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/cat.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/

#include <iostream>
#include <sstream>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
#include <typeinfo>
#include <string>
#include <list>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 

#define XOS_API __stdcall

class i_use
{
public:
    i_use( void * pThis, void * pfTest ) : obj_ptr( pThis ),
        f_test( pfTest )
    {
    }
    ~i_use()
    {
    }

public:
    const i_use & operator=( const i_use & right )
    {
        if( this != &right )
        {
            obj_ptr = right.obj_ptr;
            f_test = right.f_test;
        }
        return *this;
    }

    //////////////////////////////////////////////////////////////////////////////////////
public:
    int test( int num )
    {
        typedef int ( XOS_API * use_f_test )( void * pThis, int num );
        use_f_test f = (use_f_test)f_test;
        return f( obj_ptr, num );
    }
private:
    void * f_test;

    //////////////////////////////////////////////////////////////////////////////////////
private:
    void * obj_ptr;

};

class use_impl
{
public:
    use_impl() : m_i_use( this, static_test )
    {
    }
    ~use_impl()
    {
    }

private:
    static int XOS_API static_test( void * pThis, int num )
    {
        use_impl * pObj = (use_impl *)pThis;
        return pObj->test( num );
    }
public:
    int test( int num )
    {
        int ret = 0;
        using namespace std;
        cout << "num = " << num << endl;
        return ret;
    }

public:
    i_use * get()
    {
        return &m_i_use;
    }

private:
    i_use m_i_use;

};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main( int argc, char * argv[] )
{
    use_impl obj;
    i_use * pUse = obj.get();
    pUse->test( 10 );
    obj.test( 11 );
    return 0;
}
